import util from './util'

/**
 * point1: get position, contain scroll
 * point2: get size
 */

const Popper = function (ref, ctn, options) {
  this.ref = ref
  this.ctn = ctn

  this.presetFn = options.presetFn || function () {} // 设置前回调
  this.offsetFn = options.offsetFn || function () {} // 设置后回调

  this.placement = options.placement || 'bottom' // 方向
  this.popper = {
    placement: ''
  }
  this.refOffsetLeft = 0 // 父距离页面顶部Left（包括卷起）
  this.refOffsetTop = 0 // 父距离页面顶部Top（包括卷起）
  this.refLeft = 0 // 父距离屏幕左边距
  this.refTop = 0 // 父距离屏幕高度
  this.refRight = 0 // 父距离屏幕右边距
  this.refBottom = 0 // 父距离屏幕下边距
  this.refHeight = 0 // 父高度
  this.refWidth = 0 // 父宽度
  this.ctnWidth = 0 // 弹宽度
  this.ctnHeight = 0 // 弹高度
  this.clientWidth = document.body.clientWidth // 屏幕宽
  this.clientHeight = document.body.clientHeight // 屏幕高

  this.recordCtnWidth = 0 // 记录初始弹宽度
  this.recordCtnHeight = 0 // 记录初始弹高度

  this.isNeedScrollAndSizeUpdate = true // 是否需要滚动和resize的时候update

  this.init()
}

Popper.prototype = {
  constructor: Popper,
  init: function () {
    this.create()
    if (this.isNeedScrollAndSizeUpdate) {
      this.listen()
    }
  },

  create () {
    this.ctn.style.position = 'absolute'
    util.transEleToBody(this.ctn)
    this.update()
  },

  update () {
    // this.waitDomShow().then(() => {
      this.setCtn()
    // })
  },

  waitDomShow (cb) { // 等待display:block完成
    return new Promise(function (res, ref) {
      setTimeout(() => {
        res()
      }, 0)
    })
  },

  setCtn () {
    this.presetFn(this.ref, this.ctn)
    this.recordCtnWidth = this.recordCtnWidth === 0 ? util.getEleArg(this.ctn, 'width', 'int') : this.recordCtnWidth
    this.recordCtnHeight = this.recordCtnHeight === 0 ? util.getEleArg(this.ctn, 'height', 'int') : this.recordCtnHeight
    this.refLeft = util.getPosition(this.ref).x
    this.refTop = util.getPosition(this.ref).y
    this.refOffsetLeft = util.getOffsetPosition(this.ref).left
    this.refOffsetTop = util.getOffsetPosition(this.ref).top
    this.isToOppositeDirection()
    this.refHeight = util.getEleArg(this.ref, 'height', 'int')
    this.refWidth = util.getEleArg(this.ref, 'width', 'int')
    this.ctnHeight = util.getEleArg(this.ctn, 'height', 'int')
    this.ctnWidth = util.getEleArg(this.ctn, 'width', 'int')
    switch (this.popper.placement) {
      case 'top':
        this.setPosition({
          left: this.refOffsetLeft,
          top: this.refOffsetTop - this.ctnHeight
        })
        break
      case 'bottom':
        this.setPosition({
          left: this.refOffsetLeft,
          top: this.refOffsetTop + this.refHeight
        })
        break
      case 'left':
        this.setPosition({
          left: this.refOffsetLeft - this.ctnWidth,
          top: this.refOffsetTop
        })
        break
      case 'right':
        this.setPosition({
          left: this.refWidth + this.refOffsetLeft,
          top: this.refOffsetTop
        })
        break
      case 'none': // 可以自行设置位置
        break
    }
    this.offsetFn(this.ref, this.ctn)
  },

  isToOppositeDirection () { // 是否需要相反方向
    this.popper.placement = this.placement
    if (this.placement === 'left') {
      this.refRight = util.getPosition(this.ref).toRight
      if (this.recordCtnWidth > this.refLeft && this.refRight > this.refLeft) {
        this.popper.placement = 'right'
      }
    }
    if (this.placement === 'right') {
      this.refRight = util.getPosition(this.ref).toRight
      if (this.recordCtnWidth > this.refRight && this.refLeft > this.refRight) {
        this.popper.placement = 'left'
      }
    }
    if (this.placement === 'top') {
      this.refBottom = util.getPosition(this.ref).toBottom
      if (this.recordCtnHeight > this.refTop && this.refBottom > this.refTop) {
        this.popper.placement = 'bottom'
      }
    }
    if (this.placement === 'bottom') {
      this.refBottom = util.getPosition(this.ref).toBottom
      if (this.recordCtnHeight > this.refBottom && this.refTop > this.refBottom) {
        this.popper.placement = 'top'
      }
    }
  },

  setSize (options) {
    const { width, height } = options
    if (width) {
      this.ctn.style.width = typeof width === 'number' ? width + 'px' : width
    }
    if (height) {
      this.ctn.style.height = typeof height === 'number' ? height + 'px' : height
    }
  },

  setPosition (options) {
    const { left, top } = options
    if (left !== null) {
      this.ctn.style.left = typeof left === 'number' ? left + 'px' : left
    }
    if (top !== null) {
      this.ctn.style.top = typeof top === 'number' ? top + 'px' : top
    }
  },

  listen () {
    const deBounceUpdate = this.deBounce(this.update)
    const scrollParent = util.getScrollParent(this.ref)
    scrollParent.addEventListener('scroll', () => {
      deBounceUpdate()
    })
    window.addEventListener('resize', () => {
      deBounceUpdate()
    })
  },

  deBounce (fn) { // 防抖函数
    let isCan = true
    return () => {
      if (isCan) {
        isCan = false
        setTimeout(() => {
          isCan = true
          fn.call(this)
        }, 0)
      }
    }
  }
}
export default Popper